<template>
    <div class="container">
        <video class="local_video" ref="localVideo" width="224" height="224"></video>
        <div class="fish_box">
            <div
                class="fish"
                :class="fish.turn ? 'fish_turn' : ''"
                :style="{ top: fish.top + '%', left: fish.left + '%' }"
            ></div>
        </div>
        <div class="prepare" v-show="!isPrepared">
            <div class="prepare_title"></div>
            <div class="prepare_rule">
                <b>点击方框进行拍摄。</b
                >脸部对准镜头，按照方框的姿势拍下符合的照片。图像训练完成后便可通过转动脸部来控制小鱼的方向。
            </div>
            <div :class="'prepare_teach' + (index + 1)" v-for="(item, index) in collect">
                <div class="prepare_example" @mousedown="startCollect(index)" @mouseup="endCollect()">
                    <canvas class="prepare_canvas" ref="prepareCanvas" width="224" height="224"></canvas>
                </div>
                <div class="prepare_text">{{ item.text }}</div>
            </div>
            <div class="prepare_btn_list">
                <div class="prepare_reset_btn" @click="resetPrepare()">重置</div>
                <div class="prepare_finish_btn" @click="finishPrepare()">开始训练</div>
            </div>
            <div class="prepare_rule">TIP：训练好的图像模型，将根据实时摄像头画面进行精准预测。</div>
        </div>
    </div>
</template>
<script lang="ts" setup>
import { ref, reactive, onMounted, computed } from "vue";
import WebcamHelper from "./ts/WebcamHelper";
import { ElMessage } from "element-plus";

let localVideo = ref();
let prepareCanvas = ref();
let isPrepared = ref(false);
let isTraining = ref(false);
let webcamHelper = new WebcamHelper();

const fish = reactive({
    left: 1,
    top: 1,
    turn: false,
});

let collect = [
    { text: "向上", status: 0 },
    { text: "向下", status: 0 },
    { text: "向左", status: 0 },
    { text: "向右", status: 0 },
];

onMounted(() => {
    webcamHelper.init(localVideo.value);
});

// 开始收集图像
function startCollect(index) {
    const canvas = prepareCanvas.value[index];
    webcamHelper.startCollect(index, canvas);
    collect[index].status = 1;
}
// 结束收集图像
function endCollect() {
    webcamHelper.endCollect();
}

// 重置准备
function resetPrepare() {
    // 清空画布
    for (let canvas of prepareCanvas.value) {
        canvas.getContext("2d").clearRect(0, 0, 224, 224);
    }
    // 重置收集状态
    for (let item of collect) {
        item.status = 0;
    }
    // 清空收集
    webcamHelper.clearCollect();
}

// 完成准备
function finishPrepare() {
    if (isTraining.value) return;
    // 检查是否未全部收集
    for (let item of collect) {
        if (item.status == 0) {
            ElMessage.warning("请点击" + item.text + "方框，按照方框的姿势拍下符合的照片");
            return;
        }
    }
    isTraining.value = true;
    webcamHelper
        .train()
        .then(() => {
            isPrepared.value = true;
            isTraining.value = false;
            ElMessage.success("游戏开始！");
            predict();
        })
        .catch(() => {
            ElMessage.error("系统异常");
        });
}
// 预测
async function predict() {
    await webcamHelper.predict(moveFish);
    predict();
}
// 移动小鱼
function moveFish(code: number) {
    // 往上
    if (code == 0) {
        fish.top -= 0.8;
    }
    // 往下
    if (code == 1) {
        fish.top += 0.8;
    }
    // 往左
    if (code == 2) {
        fish.left -= 0.5;
        fish.turn = true;
    }
    // 往右
    if (code == 3) {
        fish.left += 0.5;
        fish.turn = false;
    }
    fish.top = Math.max(0, Math.min(fish.top, 100));
    fish.left = Math.max(0, Math.min(fish.left, 100));
}
</script>
<style lang="scss" scoped src="./webcam.scss"></style>
